package com.example.aigc_education.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.aigc_education.common.BusinessException;
import com.example.aigc_education.domain.Resources;
import com.example.aigc_education.domain.dto.ResourcesDTO;
import com.example.aigc_education.domain.dto.UrlDTO;
import com.example.aigc_education.domain.vo.ResourcesVO;
import com.example.aigc_education.mapper.ResourcesMapper;
import com.example.aigc_education.service.ResourcesService;
import com.example.aigc_education.service.converter.ResourcesConverter;
import com.example.aigc_education.utils.StringUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
* @author 23918
* @description 针对表【stu_resources(主题学习资源表)】的数据库操作Service实现
* @createDate 2024-11-04 19:29:25
*/
@Service
public class ResourcesServiceImpl extends ServiceImpl<ResourcesMapper, Resources>
    implements ResourcesService{

    @Resource
    private ResourcesConverter resourcesConverter;

    /**
     * 查看resources、查看链接
     *
     * 使用themeId定位 Resources数据，对原有的learningLink使用正则表达式分割，封装键值对的 links集合
     * 将resources对象转化为 resourcesVO对象（learningLink是键值对集合）
     *
     * @param themeId       主题id
     * @return              resourcesVO对象
     */
    @Override
    public ResourcesVO getResources(Long themeId) {
        try{
            LambdaQueryWrapper<Resources> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Resources::getThemeId, themeId);
            queryWrapper.orderByDesc(Resources::getCreateTime);
            // 可能存在多个资源
            List<Resources> resourcesList = this.list(queryWrapper);

            // 如果不存在resources的话返回null
            if (resourcesList.isEmpty())
                return null;
            // 取最新一个
            Resources resources = resourcesList.get(0);

            String learningLinkString = resources.getLearningLink();
            ObjectMapper objectMapper = new ObjectMapper();
            // TypeReference 指定目标类型
            List<UrlDTO> list = objectMapper.readValue(learningLinkString, new TypeReference<List<UrlDTO>>() {});

            // 将resources对象转化resourcesVO对象
            ResourcesVO resourcesVO = new ResourcesVO();
            BeanUtils.copyProperties(resources, resourcesVO);
            resourcesVO.setLearningLink(list);

            return resourcesVO;
        }catch (Exception e){
            throw new BusinessException("获取web资源失败");
        }
    }

    /**
     * 增加链接
     *
     * 用resourceId定位，获取原有的learningLink，
     * 调用StringBuilder的insert方法往原有的learningLink末尾插入新的链接
     * 最后调用Service接口的updateById更新数据库信息
     *
     * @param resourcesDTO      resourcesDTO对象，包含resourceId、新增加的learningLink
     */
    @Override
    public void addLearningLink(ResourcesDTO resourcesDTO) {
        try{
            Resources resources = this.getById(resourcesDTO.getResourceId());

            // 将对象序列化
            ObjectMapper objectMapper = new ObjectMapper();
            String learningLinkString = objectMapper.writeValueAsString(resourcesDTO.getLearningLink());


            StringBuilder learningLink = new StringBuilder(resources.getLearningLink());
            // 定义原有的learningLink长度
            int length = resources.getLearningLink().length();
            // 插入新链接
            learningLink.insert(length-1, "," + learningLinkString);
            resources.setLearningLink(learningLink.toString());

            // 更新数据库数据
            this.updateById(resources);
        }catch (Exception e){
            throw new BusinessException("添加web资源链接失败");
        }
    }


    /**
     * 保存学习资源
     *
     * 先调用 ResourcesConverter 使 ResourcesVO --> Resources
     * （ 调用时候，忽略 learningLink ）
     * 这时候，序列化集合，再 set 到 Resources 对象中，再保存到数据库
     *
     * @param resourcesVO   获取resources的VO对象
     *
     */
    @Override
    public void saveResources(ResourcesVO resourcesVO) {
        try{
            Resources resources = resourcesConverter.resourcesVOToResources(resourcesVO);
            // 获取集合
            List<UrlDTO> urlDTOList = resourcesVO.getLearningLink();

            // 序列化对象
            ObjectMapper objectMapper = new ObjectMapper();
            String learningLink = objectMapper.writeValueAsString(urlDTOList);
            resources.setLearningLink(learningLink);
//            System.out.println(resources);

            this.save(resources);

        }catch (Exception e){
            throw new BusinessException("保存学习资源异常");
        }
    }

    /**
     * 通过学习资源id查询学习资源
     * 调用mybatis的getById直接查询
     * 出现异常返回错误信息：获取学习资源异常
     *
     * @param id 学习资源id
     * @return Resources
     */
    @Override
    public ResourcesVO getResourcesById(Long id) {
        try{
            LambdaQueryWrapper<Resources> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Resources::getResourceId, id);
            queryWrapper.eq(Resources::getStatus, 1);

            Resources resources = this.getOne(queryWrapper);
            if (StringUtils.isNull(resources))
                return null;

            String learningLinkString = resources.getLearningLink();
            ObjectMapper objectMapper = new ObjectMapper();
            // TypeReference 指定目标类型
            List<UrlDTO> list = objectMapper.readValue(learningLinkString, new TypeReference<List<UrlDTO>>() {});

            ResourcesVO resourcesVO = resourcesConverter.resourcesToResourcesVO(resources);
            resourcesVO.setLearningLink(list);

            return resourcesVO;

        }catch (Exception e){
            throw new BusinessException("获取学习资源异常");
        }
    }
}




